import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

def data_from_csv():
    df = pd.read_csv('../data/watermelon-3a.csv')

    #读出正反类
    data_pos = df[df['classification'] == 1]
    data_neg = df[df['classification'] == 0]

    #取出特征
    x_pos = np.array(data_pos[['density','sugar']])
    x_neg = np.array(data_neg[['density','sugar']])

    return x_pos, x_neg, df
    


# =============== step 1/4 加载正反类数据 ===============
x_pos, x_neg, df = data_from_csv()
print(x_pos)

# =============== step 2/4 按列求均值，转为列向量 ===============
mean_pos = np.mean(x_pos, axis=0).reshape((-1, 1))
mean_neg = np.mean(x_neg, axis=0).reshape((-1, 1))

# =============== step 3/4 计算类内散度矩阵Sw ===============
Si_pos = np.cov(x_pos, rowvar=False)#列为元素
Si_neg = np.cov(x_neg, rowvar=False)
Sw = Si_pos + Si_neg

# =============== step 4/4 求解w ===============
Sw = np.mat(Sw)
w = Sw.I * (mean_pos - mean_neg)





w = [w[0,0], w[1,0]]
print(w)
# =============== 绘制 ===============

# y = k * x
# y = -1/k * x + b
# 经过一点的垂线的交点
def cal_cross_dot(k0, x, y):
    b = y + 1 / k0 *x
    x = b / ( k0 + 1/k0 )
    y = k0 * x
    return x, y


#绘制样本点
sns.set()
sns.scatterplot(data=df, x='density', y='sugar',hue='classification')

#绘制直线
x_line = np.arange(0, 1, 0.05)
k = -w[0] / w[1]
y_line =  k * x_line

plt.plot(x_line, y_line)


cross_pos_x = []
cross_pos_y = []
for i in range(len(x_pos)):
    density, sugar = x_pos[i][0], x_pos[i][1]
    # print(density, sugar)
    x_cross, y_cross = cal_cross_dot(k, density, sugar)
    cross_pos_x.append(x_cross)
    cross_pos_y.append(y_cross)

    plt.plot([density, x_cross], [sugar, y_cross], c = 'sandybrown', linestyle = '--')


cross_neg_x = []
cross_neg_y = []
for i in range(len(x_neg)):
    density, sugar = x_neg[i][0], x_neg[i][1]
    # print(density, sugar)
    x_cross, y_cross = cal_cross_dot(k, density, sugar)
    cross_neg_x.append(x_cross)
    cross_neg_y.append(y_cross)
    plt.plot([density, x_cross], [sugar, y_cross], c = 'lightsteelblue', linestyle = '--')


sns.scatterplot(x = cross_pos_x, y = cross_pos_y, c = 'sandybrown')
sns.scatterplot(x = cross_neg_x, y = cross_neg_y, c = 'lightsteelblue' )


plt.title('Linear Discriminant Analysis', fontproperties='SimHei')
plt.show()

'''
以下是之前的错误代码
之前在计算协方差矩阵时，手撸出错了
'''

# print(mean_pos, mean_neg, Sw)

# Sw = np.mat(Sw)
# Sw_inv = np.linalg.pinv(Sw)
# print('inv:{}'.format(Sw_inv))

# print(Sw_inv, Sw_inv.shape)
# Sw_inv = np.array([Sw_inv[0,0],Sw_inv[1,0]])

# print(Sw_inv)
# print(mean_pos - mean_neg)
# w = Sw_inv*(mean_pos-mean_neg)
# print(w)


#ax2 = plt.axes(projection='3d')

# ax2.scatter3D(x_pos[:,0],x_pos[:,1],1,c='g',marker='+',s=35,label="category 1")
# ax2.scatter3D(x_neg[:,0],x_neg[:,1],-1,c='r',marker='o',s=30,label="category -1")

# x1 = np.arange(-1,1,0.05)
# x2 = np.arange(-1,1,0.05)
# x1, x2 = np.meshgrid(x1,x2)
# Y = w[0]*x1 + w[1]*x2

# ax2.plot_surface(x1,x2,Y,cmap=plt.cm.coolwarm)

#plt.legend()
#plt.title("w0,w1=[{:3f} {:3f}]".format(w[0], w[1]))
